package com.atguigu.jxc.service.impl;

import com.atguigu.jxc.dao.GoodsDao;
import com.atguigu.jxc.dao.PurchaseListGoodsDao;
import com.atguigu.jxc.dao.UserDao;
import com.atguigu.jxc.domain.ServiceVO;
import com.atguigu.jxc.domain.SuccessCode;
import com.atguigu.jxc.entity.Goods;
import com.atguigu.jxc.entity.PurchaseList;
import com.atguigu.jxc.entity.PurchaseListGoods;
import com.atguigu.jxc.entity.User;
import com.atguigu.jxc.service.PurchaseListGoodsService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.atguigu.jxc.dao.PurchaseListGoodsDao;
import com.atguigu.jxc.entity.Goods;
import com.atguigu.jxc.entity.PurchaseList;
import com.atguigu.jxc.entity.PurchaseListGoods;
import com.atguigu.jxc.service.PurchaseListGoodsService;
import com.atguigu.jxc.vo.GoodVo;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

@Service
public class PurchaseListGoodsServiceImpl implements PurchaseListGoodsService {
    @Autowired
    private PurchaseListGoodsDao purchaseListGoodsDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private GoodsDao goodsDao;

    private static final ObjectMapper MAPPER = new ObjectMapper();


    @Override
    public List<Map<String,Object>> list(String purchaseNumber, Integer supplierId, Integer state, String sTime, String eTime) {
        List<Map<String,Object>> map = purchaseListGoodsDao.list(purchaseNumber,supplierId,state,sTime,eTime);

        return map;
    }

    @Override
    public List<Map<String, Object>> goodsList(Integer purchaseListId) {
        return purchaseListGoodsDao.goodsList(purchaseListId);
    }

    @Override
    public void delete(Integer purchaseListId) {
        purchaseListGoodsDao.deleteGoodsByPurchaseListId(purchaseListId);
        purchaseListGoodsDao.delete(purchaseListId);
    }

    /**
     * 支付结算（修改进货单付款状态）
     *
     * @param purchaseListId
     * @return
     */
    @Override
    public void updateState(Integer purchaseListId) {
        this.purchaseListGoodsDao.updateState(purchaseListId);
    }

    /**
     * 进货统计（可根据 商品类别、商品编码或名称 条件查询）
     * @param sTime
     * @param eTime
     * @param goodsTypeId
     * @param codeOrName
     * @return
     */
    @Override
    public List<GoodVo> count(String sTime, String eTime, Integer goodsTypeId, String codeOrName) {
        // 两者都不为 null 时，查询，否则即查询全部
        List<GoodVo> goodVos = this.purchaseListGoodsDao.count(sTime,eTime,goodsTypeId,codeOrName);
        return goodVos;
    }

    @Override
    public void save(PurchaseList purchaseList, String purchaseListGoodsStr) {
        try {
            // 1. 保存进货清单
            //      设置当前操作用户
            User currentUser = userDao.findUserByName((String) SecurityUtils.getSubject().getPrincipal());
            purchaseList.setUserId(currentUser.getUserId());
            this.purchaseListGoodsDao.savePurchaseList(purchaseList);

            // 2. 保存货物更新单，有多个
            //      解析 json
            List<PurchaseListGoods> purchaseListGoodsList = MAPPER.readValue(purchaseListGoodsStr, new TypeReference<List<PurchaseListGoods>>() { });
            purchaseListGoodsList.forEach(purchaseListGoods -> {
                // 获取该货物单的货物
                Goods goods = goodsDao.findByGoodsId(purchaseListGoods.getGoodsId());
                // 设置进货清单编号
                purchaseListGoods.setPurchaseListId(purchaseList.getPurchaseListId());
                // 设置货物种类编号
                purchaseListGoods.setGoodsTypeId(goods.getGoodsTypeId());
                // 保存
                this.purchaseListGoodsDao.savePurchaseListGoods(purchaseListGoods);

                // 3. 更新货存信息
                // 更新库存数量
                goods.setInventoryQuantity(goods.getInventoryQuantity() + purchaseListGoods.getGoodsNum());
                // 上次进货价格
                goods.setLastPurchasingPrice(purchaseListGoods.getPrice());
                this.goodsDao.updateGoods(goods);
            });


        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("解析 json 失败");
        }
    }
}
